package com.cn.springcloudwechat.common.weiXinPay;

import com.cn.springcloudwechat.common.utils.ThreadLocalUtil;
import com.cn.springcloudwechat.common.utils.XMLParser;
import com.cn.springcloudwechat.common.utils.base.Const;
import com.cn.springcloudwechat.common.utils.weixin.util.ConfigReader;
import com.cn.springcloudwechat.common.weiXinPay.sortUntil.SortUtil;
import com.cn.springcloudwechat.common.weiXinPay.weiXinSina.Sina;
import com.cn.springcloudwechat.common.weiXinPay.xmlUntil.XMLUtil;
import org.xml.sax.SAXException;
import net.sf.json.JSONObject;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

//微信h5支付
@XmlAccessorType(XmlAccessType.FIELD)
// XML文件中的根标识
@XmlRootElement(name = "xml")
// 控制JAXB 绑定类中属性和字段的排序
@XmlType(propOrder = {"appid", "mch_id", "notify_url", "trade_type", "spbill_create_ip", "nonce_str", "sign", "body",
        "out_trade_no", "total_fee", "scene_info","openid","attch"})
public class WeiXinPayConfig implements Serializable {
    private static final ConfigReader _cr = new ConfigReader(Const.WEIXIN_PAY_CONFIG);
    private static final long serialVersionUID = 1L;
    public static String pay_url="https://api.mch.weixin.qq.com/pay/unifiedorder";//支付地址
    public static String key="ebb5236a3ad0d5ab386bc114b5b77efd"; //支付密钥
    private String appid;// 公众账号ID
    private String mch_id;// 商户号
    private String notify_url;// 通知地址
    private String trade_type;// 交易类型 h5支付 JSAPI公众号支付
    private String spbill_create_ip;// 终端IP
    private String nonce_str;// 随机字符串
    private String sign;// 签名
    private String body;// 商品描述
    private String out_trade_no;// 商户订单号
    private int total_fee;// 总金额(分)
    private String scene_info;// 场景信息
    private String openid;//商户对应appid下的唯一标识
    private String attch;//自定义参数

    // {"h5_info": {"type":"Wap","wap_url": "https://pay.qq.com","wap_name":
    // "腾讯充值"}}

    public static String init(HttpServletRequest request,Integer totalFee,String body) {
        WeiXinPayConfig weiXinPayConfig = new WeiXinPayConfig();
        // 修改为实际的公众号信息,可以在开发者栏目中查看
        weiXinPayConfig.setAppid(_cr.get("appid"));
        weiXinPayConfig.setMch_id(_cr.get("mch_id"));
        weiXinPayConfig.setNotify_url(_cr.get("notify_url"));
        weiXinPayConfig.setSpbill_create_ip(weiXinPayConfig.getRquestIpAddr(request));
        weiXinPayConfig.setNonce_str(weiXinPayConfig.getNonceStr());
        weiXinPayConfig.setOut_trade_no((String) ThreadLocalUtil.getRequest().getSession().getAttribute("outTradeNo"));
        weiXinPayConfig.setTrade_type("JSAPI");
        weiXinPayConfig.setBody(body);
        weiXinPayConfig.setTotal_fee(totalFee);
//        if (request.getParameter("type").equalsIgnoreCase("h5")) {
//            weiXinPayConfig.setScene_info(weiXinPayConfig.getSceneInfo());
//        }
//        if(request.getParameter("attch")!=null){
//            weiXinPayConfig.setAttch(request.getParameter("attch"));
//        }
        weiXinPayConfig.setSign(weiXinPayConfig.getSignMeth(weiXinPayConfig));
        return XMLUtil.convertToXml(weiXinPayConfig);
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getMch_id() {
        return mch_id;
    }

    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getTrade_type() {
        return trade_type;
    }

    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }

    public String getSpbill_create_ip() {
        return spbill_create_ip;
    }

    public void setSpbill_create_ip(String spbill_create_ip) {
        this.spbill_create_ip = spbill_create_ip;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public int getTotal_fee() {
        return total_fee;
    }

    public void setTotal_fee(int total_fee) {
        this.total_fee = total_fee;
    }

    public String getScene_info() {
        return scene_info;
    }

    public void setScene_info(String scene_info) {
        this.scene_info = scene_info;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getAttch() {
        return attch;
    }

    public void setAttch(String attch) {
        this.attch = attch;
    }

    public String getSignMeth(WeiXinPayConfig weiXinPayConfig) {
        SortedMap<Object,Object> beanToMap = SortUtil.beanToMap(weiXinPayConfig);
        return Sina.createSign(beanToMap);
    }

    public  String getOutTradeNo() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
        out_trade_no = df.format(new Date());// new Date()为获取当前系统时间
        out_trade_no = out_trade_no + (UUID.randomUUID().toString().trim().replaceAll("-", "").substring(0, 13));
        return out_trade_no;
    }

    /**
     * 获取随机支付串
     *
     * @return
     */
    public static String getNonceStr() {
        return UUID.randomUUID().toString().trim().replaceAll("-", "");
    }

    public String getSceneInfo() {
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("type", "Wap");
        jsonObject1.put("wap_url", "https://pay.qq.com");
        jsonObject1.put("wap_name", "腾讯充值");
        jsonObject.put("h5_info", jsonObject1);
        return jsonObject.toString();
    }

    // 获取用户真实ip
    public  String  getRquestIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    @Override
    public String toString() {
        return "WeiXinPayConfig{" +
                "appid='" + appid + '\'' +
                ", mch_id='" + mch_id + '\'' +
                ", notify_url='" + notify_url + '\'' +
                ", trade_type='" + trade_type + '\'' +
                ", spbill_create_ip='" + spbill_create_ip + '\'' +
                ", nonce_str='" + nonce_str + '\'' +
                ", sign='" + sign + '\'' +
                ", body='" + body + '\'' +
                ", out_trade_no='" + out_trade_no + '\'' +
                ", total_fee=" + total_fee +
                ", scene_info='" + scene_info + '\'' +
                ", openid='" + openid + '\'' +
                ", attch='" + attch + '\'' +
                '}';
    }

    /**
     * 微信第二次签名
     * @param result
     * @return
     */
    public static Map<Object, Object> secondSign(String result) {
        WeiXinPayConfig weiXinPayConfig = new WeiXinPayConfig();
        SortedMap<Object, Object> params = new TreeMap<Object, Object>();
        Map<Object, Object> maps = new HashMap<>();
        try {
            Map<String, Object> map = XMLParser.getMapFromXML(result);
            System.out.println(map.toString());
            if (map.get("return_code").equals("SUCCESS") && map.get("return_msg").equals("OK")) {
                String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
                params.put("appId", map.get("appid"));
                params.put("timeStamp", timeStamp);
                params.put("nonceStr", weiXinPayConfig.getNonce_str());
                params.put("package", "prepay_id=" + map.get("prepay_id"));
                params.put("signType", "MD5");
                String paySign = Sina.createSign(params);
                params.put("paySign", paySign);
                System.out.println("签名->" + paySign);
                params.put("pg", "prepay_id=" + map.get("prepay_id"));
                System.out.println(params);
            } else if (map.get("return_code").equals("NOTENOUGH")) {
                // 用户余额不足
            } else if ("ORDERPAID".equals(map.get("err_code"))) {
                // 商户订单已支付，无需重复操作
            } else if ("SYSTEMERROR".equals(map.get("err_code"))) {
                // 系统超时
            } else if ("ORDERCLOSED".equals(map.get("err_code"))) {
                // 参数中缺少APPID
            } else if ("APPID_NOT_EXIST".equals(map.get("err_code"))) {
                // 当前订单已关闭，无法支付
            } else if ("MCHID_NOT_EXIST".equals(map.get("err_code"))) {
                // 参数中缺少MCHID
            } else if ("APPID_MCHID_NOT_MATCH".equals(map.get("err_code"))) {
                // appid和mch_id不匹配
            } else if ("LACK_PARAMS".equals(map.get("err_code"))) {
                // 缺少必要的请求参数
            } else if ("OUT_TRADE_NO_USED".equals(map.get("err_code"))) {
                // 同一笔交易不能多次提交
            } else if ("SIGNERROR".equals(map.get("err_code"))) {
                // 参数签名结果不正确
            } else if ("XML_FORMAT_ERROR".equals(map.get("err_code"))) {
                // XML格式错误
            } else if ("REQUIRE_POST_METHOD".equals(map.get("err_code"))) {
                // 未使用post传递参数
            } else if ("POST_DATA_EMPTY".equals(map.get("err_code"))) {
                // post数据不能为空
            } else if ("NOT_UTF8".equals(map.get("err_code"))) {
                // 未使用指定编码格式
            }
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        maps.put("data", params);
        maps.put("weiXinPayConfig", weiXinPayConfig);
        return maps;
    }
    public static void main(String[] args) {
        System.out.println("123");
	/*	WeiXinPayConfig weiXinPayConfig=new WeiXinPayConfig("123","body",11);
		System.out.println(weiXinPayConfig.toString());*/
    }
}
